package com.example.pack;

import com.example.pack.util.PackUtil;
import com.example.pack.util.ProjectDataUtil;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Callback;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class MainController {

    @FXML
    private ChoiceBox<String> projectName;

    @FXML
    private DatePicker startDatePicker;

    @FXML
    private DatePicker endDatePicker;

    @FXML
    private TextField startVersion;

    @FXML
    private TextField endVersion;

    @FXML
    private Label prompt;

    /**
     * 主窗口初始化方法
     */
    public void initialize() {
        // 项目名称下拉框初始化
        choicesInit();
        // 日期选择框初始化
        datePickerInit();
        // 版本号输入框初始化
        versionInit();
    }

    /**
     * 项目名称下拉框初始化
     */
    public void choicesInit(){
        ObservableList<String> choices = FXCollections.observableArrayList();
        ProjectDataUtil.choicesInit(choices);
        projectName.setItems(choices);
    }

    /**
     * 日期选择框初始化
     */
    public void datePickerInit(){
        // 日期选择框默认值为当天日期
        startDatePicker.setValue(LocalDate.now());
        endDatePicker.setValue(LocalDate.now());
        // 设置初始日期不能大于结束日期
        startDatePicker.valueProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null && endDatePicker.getValue() != null && newVal.isAfter(endDatePicker.getValue())) {
                startDatePicker.setValue(endDatePicker.getValue());
            }
        });
        // 设置结束日期不能小于初始日期
        endDatePicker.valueProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null && startDatePicker.getValue() != null && newVal.isBefore(startDatePicker.getValue())) {
                endDatePicker.setValue(startDatePicker.getValue());
            }
        });
    }

    /**
     * 版本号输入框初始化
     */
    public void versionInit(){
        // 起始版本号必须为数字
        startVersion.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("\\d*")) {
                startVersion.setText("");
            }
        });
        // 结束版本号必须为数字
        endVersion.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("\\d*")) {
                endVersion.setText("");
            }
        });
    }

    /**
     * 打开添加项目配置窗口
     * @param event
     * @throws IOException
     */
    @FXML
    private void add(ActionEvent event) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("save-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        Stage newWindow = new Stage();
        newWindow.setTitle("新增");
        newWindow.setScene(scene);
        // 设置窗口关闭时的事件处理器，关闭窗口时重新加载项目名称下拉选择框列表内容
        newWindow.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                choicesInit();
            }
        });
        newWindow.show();
    }

    /**
     * 打开已保存的项目配置列表，可在列表中删除记录
     * @param event
     */
    @FXML
    private void list(ActionEvent event) {
        Stage primaryStage = new Stage();
        TableView<WebProject> tableView = new TableView<>();
        // 设置表头
        TableColumn<WebProject, String> nameColumn = new TableColumn<>("项目名称");
        nameColumn.setMinWidth(100);
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("projectName"));
        TableColumn<WebProject, String> svnPathColumn = new TableColumn<>("SVN地址");
        svnPathColumn.setMinWidth(250);
        svnPathColumn.setCellValueFactory(new PropertyValueFactory<>("svnPath"));
        TableColumn<WebProject, String> projectPathColumn = new TableColumn<>("项目路径");
        projectPathColumn.setMinWidth(250);
        projectPathColumn.setCellValueFactory(new PropertyValueFactory<>("projectPath"));
        TableColumn<WebProject, String> classPathColumn = new TableColumn<>("ClassPath路径");
        classPathColumn.setMinWidth(150);
        classPathColumn.setCellValueFactory(new PropertyValueFactory<>("classPath"));

        // 添加删除按钮及绑定按钮点击事件
        TableColumn<WebProject, Button> actionColumn = new TableColumn<>("操作");
        actionColumn.setMinWidth(50);
        actionColumn.setCellFactory(new Callback<TableColumn<WebProject, Button>, TableCell<WebProject, Button>>() {
            @Override
            public TableCell<WebProject, Button> call(TableColumn<WebProject, Button> param) {
                return new TableCell<WebProject, Button>() {
                    private final Button btnDelete = new Button("删除");
                    {
                        btnDelete.setOnAction(event -> {
                            int index = getIndex();
                            ProjectDataUtil.delete(tableView.getItems().get(index).getProjectName());
                            choicesInit();
                            tableView.getItems().remove(index);
                        });
                    }
                    @Override
                    protected void updateItem(Button item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(btnDelete);
                        }
                    }
                };
            }
        });
        tableView.getColumns().addAll(nameColumn,svnPathColumn,projectPathColumn,classPathColumn,actionColumn);
        // 拼接已储存的项目信息
        ObservableList<WebProject> data = FXCollections.observableArrayList(
                ProjectDataUtil.getProjectList()
        );
        tableView.setItems(data);
        VBox vBox = new VBox(tableView);
        Scene scene = new Scene(vBox, 810, 400);
        primaryStage.setTitle("项目列表");
        primaryStage.setScene(scene);
        // 设置窗口关闭时的事件处理器，关闭窗口时重新加载项目名称下拉选择框列表内容
        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                choicesInit();
            }
        });
        primaryStage.show();
    }

    /**
     * 打开使用说明窗口
     * @param event
     * @throws IOException
     */
    @FXML
    private void explain(ActionEvent event) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("explain-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        Stage newWindow = new Stage();
        newWindow.setTitle("使用说明");
        newWindow.setScene(scene);
        newWindow.show();
    }
    /**
     * 增量打包并将更新包生成到桌面
     */
    @FXML
    protected void doPack() {
        if (check()) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String startVersionText = startVersion.getText();
            String endVersionText = endVersion.getText();
            int tok = PackUtil.doPack(ProjectDataUtil.get(projectName.getValue()),startDatePicker.getValue().format(formatter),endDatePicker.getValue().format(formatter), startVersionText.length()>0 ? Integer.valueOf(startVersionText) : null, endVersionText.length()>0 ? Integer.valueOf(endVersionText) : null);
            if (tok==1) {
                packAfter("打包成功");
            }else if(tok==2){
                packAfter("打包失败");
            }else{
                packAfter("当前条件范围内无更新文件");
            }
        }
    }

    /**
     * 校验数据正确性
     * @return false 查询条件未通过校验 true 通过校验
     */
    public boolean check(){
        if (projectName.getValue() == null || projectName.getValue().isEmpty()) {
            prompt.setText("请选择项目");
            return false;
        }
        if (!startVersion.getText().isEmpty() && !endVersion.getText().isEmpty() && Integer.parseInt(startVersion.getText()) > Integer.parseInt(endVersion.getText())) {
            prompt.setText("起始版本号不得大于结束版本号");
            return false;
        }
        return true;
    }

    /**
     * 打包后执行事件
     * @param text 提示语句
     */
    public void packAfter(String text){
        prompt.setText(text);
        projectName.setValue("");
        startDatePicker.setValue(LocalDate.now());
        endDatePicker.setValue(LocalDate.now());
        startVersion.setText("");
        endVersion.setText("");
    }
}